#' copied from mlr and slightly adapted
analyzeFeatSelResult = function(x, y, op, all.elements) {
  measure = op$y.names[1L]
  minimize = op$minimize[measure]
  ctrl = res$control
  width.feat = 20L
  width.num = 8L
  reduce = TRUE



  numToString = function(x) sprintf("%.5g", x)

  ##### print path

  ### produce df data.frame that contains all info
  df = as.data.frame(op)
  features = setdiff(colnames(df), c("y", "dob", "eol"))

  # convert measure to text

  # feature was selected when it never "died" or it "died" in later iteration
  df$sel = (is.na(df$eol) | (df$dob < df$eol))
  df$opt = is.na(df$eol)
  # number of features in set are sum of bits which are 1
  df$n.feats = rowSums(df[, features, drop = FALSE])
  df = df[df$sel,, drop =FALSE]

  ### Initialize some variables
  old.feats = features[df[1L, features, drop = TRUE] == 1]
  old.perf = NA_real_
  res = data.frame()

  ### Iterate over all dobs / steps per dob and print info for each
  for (thedob in unique(df$dob)) {
    df.dob = subset(df, df$dob == thedob)
    df.sel = subset(df.dob, df.dob$sel == TRUE)
    for (j in seq_row(df.dob)) {
      row = df.dob[j, ]
      cur.feats = features[row[features] == 1]
      cur.sel = ifelse(row$sel, "*", " ")
      cur.perf = row[, measure]
      if (thedob == 1L)
        change.feat = ""
      else
        change.feat = symdiff(cur.feats, old.feats)

      cf2 = mapValues(change.feat, features, all.elements)
      res = rbind(res, data.frame(add = cf2, perf = cur.perf, diff = old.perf - cur.perf))
      # catf("- Features: %4i  %s : %-20s  Perf = %s  Diff: %s  %s",
        # length(cur.feats), change.txt, clipString(change.feat, width.feat),
        # numToString(cur.perf),
        # numToString(ifelse(minimize, 1, -1) * (old.perf - cur.perf)),
        # cur.sel)
    }
    # in last block be might not have selected any state because no improvement
    if (nrow(df.sel) > 0L) {
      old.feats = features[df.sel[, features, drop = TRUE] == 1L]
      old.perf = df.sel[, measure]
    }
  }

  return(res)
}


